# -*- coding: utf-8 -*-
import math
import pickle
from abc import abstractmethod
from app.models import Base
from app.models import id
from app.models import date_time
from app.models import create_time
from app.models import update_time
from app.models import text
from app.models import string
from app.models import string_index
from app.models import integer
from app.models import float
from app.models import largebinary
from app.models import longblob
from app.models import largebinary_loads
from app.models import largebinary_dumps
from app.tools.utils import dt2str
from app.tools.utils import vec3arr
from ezdxf.math.ellipse import minor_axis
from ezdxf.math import Vec3
from app.tools.utils import box, arc, ellipse


class MineModel(Base):
    """ 煤矿信息 """
    __tablename__ = 'mine'

    id = id()
    mine_code = string(comment='矿井编号')
    mine_name = string(comment='矿井中文名称')
    mine_pinyin = string(comment='矿井拼音名称')
    mine_pinyin_first = string(comment='矿井拼音首字母')
    mine_yield = float(comment='矿井产量')
    mine_yield_check = float(comment='核定生产能力')
    check_date = create_time(comment='核定日期')
    provice = string(comment='省')
    city = string(comment='市')
    county = string(comment='县')
    township = string(comment='乡/镇')
    address = string(comment='详细地址信息')
    provincial_office = string(comment='所属省局信息')
    suboffice_name = string(comment='矿井所属分局名称')
    group_name = string(comment='矿井所属集团名称')
    coalseam_num = integer(comment='可采煤层数')
    mine_area = float(comment='井田面积')
    build_time = create_time(comment='建矿时间')
    longitude = float(comment='经度')
    latitude = float(comment='纬度')
    description = text(comment='矿井简介')
    mine_status = integer(comment='矿井状态')
    gas_level = integer(comment='瓦斯等级')
    water_condition = integer(comment='矿井水文地质条件')
    rock_burst_tendency = integer(comment='煤岩冲击倾向性')
    burst_danger_level = integer(comment='冲击危险性等级')
    roof_hazard_type = integer(comment='顶板灾害类型')
    coal_fire_tendency = integer(comment='煤自燃倾向性')
    dust_explosion_danger = integer(comment='粉尘爆炸危险性')

    def info(self):
        cont = dict()
        cont['code'] = self.mine_code
        cont['name'] = self.mine_name
        cont['address'] = self.address
        cont['longitude'] = self.longitude
        cont['latitude'] = self.latitude
        return cont


class DXFModel(Base):
    __abstract__ = True

    id = id()
    meta_id = string_index(index=True)
    create_time = create_time()
    update_time = update_time()

    @abstractmethod
    def dxf(self):
        cont = dict()
        cont['id'] = self.id
        cont['meta_id'] = self.meta_id
        cont['create_time'] = dt2str(self.create_time)
        cont['update_time'] = dt2str(self.update_time)
        return cont


class ExtentModel(DXFModel):
    __abstract__ = True

    left = float()
    right = float()
    top = float()
    bottom = float()
    x = float()
    y = float()

    @abstractmethod
    def dxf(self):
        cont = super().dxf()
        cont['left'] = self.left
        cont['right'] = self.right
        cont['top'] = self.top
        cont['bottom'] = self.bottom
        cont['x'] = self.x
        cont['y'] = self.y
        cont['meta_id'] = self.meta_id
        return cont


class EntityModel(ExtentModel):
    __abstract__ = True

    layer = string_index(index=True)
    dxftype = string_index(index=True)
    color = integer(index=True)
    linetype = string_index(index=True)
    lineweight = integer()
    insert_id = string_index(index=True)
    handle = string()
    owner = string()

    def __init__(self, entity=None, meta_id=None, insert_id=None):
        # 0.如果entity或meta_id有一个为空，则不继续初始化
        if entity is None or meta_id is None:
            return

        # 1.要初始化DXFModel本身的内容
        if 'dxftype' in dir(entity):
            self.dxftype = entity.dxftype()
        if hasattr(entity, 'dxf') and hasattr(entity.dxf, 'layer'):
            self.layer = entity.dxf.layer
        if hasattr(entity, 'dxf') and hasattr(entity.dxf, 'color'):
            self.color = entity.dxf.color
        if hasattr(entity, 'dxf') and hasattr(entity.dxf, 'handle'):
            self.handle = entity.dxf.handle
        if hasattr(entity, 'dxf') and hasattr(entity.dxf, 'owner'):
            self.owner = entity.dxf.owner
        if hasattr(entity, 'dxf') and hasattr(entity.dxf, 'linetype'):
            self.linetype = entity.dxf.linetype
        if hasattr(entity, 'dxf') and hasattr(entity.dxf, 'lineweight'):
            self.lineweight = entity.dxf.lineweight
        self.meta_id = meta_id
        self.insert_id = insert_id

        # 2.模板初始化子类的内容
        self.init(entity)

    @abstractmethod
    def init(self, entity):
        pass

    @abstractmethod
    def dxf(self):
        cont = super().dxf()
        cont['dxf'] = dict()
        cont['dxf']['layer'] = self.layer
        cont['dxf']['color'] = self.color
        # cont['dxf']['handle'] = self.handle
        # cont['dxf']['owner'] = self.owner
        cont['insert_id'] = self.insert_id
        return cont

    @abstractmethod
    def vector(self):
        cont = dict()
        cont['id'] = self.id
        cont['meta_id'] = self.meta_id
        cont['left'] = self.left
        cont['right'] = self.right
        cont['top'] = self.top
        cont['bottom'] = self.bottom
        cont['x'] = self.x
        cont['y'] = self.y
        cont['layer'] = self.layer
        cont['color'] = self.color
        cont['insert_id'] = self.insert_id
        return cont


class MetaModel(ExtentModel):
    __tablename__ = 'meta'

    name = string_index(index=True)
    mine_code = string(comment='煤矿编码')
    mine_name = string(comment='煤矿名称')
    sign = string(comment='标志/煤层编码')
    type = string(comment='矿图类型编码')
    piece = string(comment='矿图图件编码')
    major_ver = string(comment='主版本')
    minor_ver = integer(comment='副版本')
    cs = string(comment='坐标系统编码')

    def dxf(self):
        cont = super().dxf()
        cont['name'] = self.name
        cont['mine_code'] = self.mine_code
        cont['mine_name'] = self.mine_name
        cont['sign'] = self.sign
        cont['type'] = self.type
        cont['piece'] = self.piece
        cont['major_ver'] = self.major_ver
        cont['minor_ver'] = self.minor_ver
        cont['cs'] = self.cs
        return cont


class HeaderModel(DXFModel):
    __tablename__ = 'header'

    acad_compatible = largebinary()
    acad_release = string()
    dxfversion = string()
    encoding = string()
    is_loading = largebinary()
    loaded_dxfversion = string()
    output_encoding = string()
    units = integer()
    hdrvars = largebinary()
    styles = largebinary()

    def __init__(self, doc, meta_id):
        self.meta_id = meta_id
        self.acad_release = doc.acad_release
        self.dxfversion = doc.dxfversion
        self.encoding = doc.encoding
        self.is_loading = pickle.dumps(doc.is_loading)
        self.loaded_dxfversion = doc.loaded_dxfversion
        self.output_encoding = doc.output_encoding
        self.units = doc.units
        self.hdrvars = pickle.dumps(doc.header.hdrvars)

    def dxf(self):
        cont = dict()
        cont['acad_release'] = self.acad_release
        cont['dxfversion'] = self.dxfversion
        cont['encoding'] = self.encoding
        cont['is_loading'] = largebinary_loads(self.is_loading)
        cont['loaded_dxfversion'] = self.loaded_dxfversion
        cont['output_encoding'] = self.output_encoding
        cont['units'] = self.units
        cont['hdrvars'] = largebinary_loads(self.hdrvars)
        return cont


class LayerModel(EntityModel):
    __tablename__ = 'layer'

    name = string()
    flags = string()
    plotstyle_handle = string()
    material_handle = string()

    def init(self, entity):
        self.layer = self.name = entity.dxf.name
        self.flags = entity.dxf.flags
        self.plotstyle_handle = entity.dxf.plotstyle_handle
        self.material_handle = entity.dxf.material_handle

    def dxf(self):
        cont = dict()
        cont['id'] = self.id
        cont['name'] = self.name
        cont['color'] = self.color
        cont['linetype'] = self.linetype
        cont['meta_id'] = self.meta_id
        return cont

    def vector(self):
        cont = dict()
        cont['id'] = self.id
        cont['meta_id'] = self.meta_id
        cont['layer'] = self.layer
        return cont


class StyleModel(DXFModel):
    __tablename__ = 'style'

    handle = string()
    owner = string()
    dxftype = string()
    bigfont = string()
    flags = integer()
    font = string()
    generation_flags = integer()
    height = float()
    last_height = float()
    name = string()
    oblique = float()
    width = float()

    def __init__(self, entity, meta_id):
        self.meta_id = meta_id
        self.dxftype = entity.dxf.dxftype
        self.handle = entity.dxf.handle
        self.owner = entity.dxf.owner
        self.bigfont = entity.dxf.bigfont
        self.flags = entity.dxf.flags
        self.font = entity.dxf.font
        self.generation_flags = entity.dxf.generation_flags
        self.height = entity.dxf.height
        self.last_height = entity.dxf.last_height
        self.name = entity.dxf.name
        self.oblique = entity.dxf.oblique
        self.width = entity.dxf.width

    def dxf(self):
        cont = dict()
        cont['dxf'] = dict()
        cont['dxf']['owner'] = self.owner
        cont['dxf']['bigfont'] = self.bigfont
        cont['dxf']['flags'] = self.flags
        cont['dxf']['font'] = self.font
        cont['dxf']['generation_flags'] = self.generation_flags
        cont['dxf']['height'] = self.height
        cont['dxf']['last_height'] = self.last_height
        cont['dxf']['name'] = self.name
        cont['dxf']['oblique'] = self.oblique
        cont['dxf']['width'] = self.width
        return cont


class DimstyleModel(DXFModel):
    __tablename__ = 'dimstyle'

    dxftype = string()
    flags = integer()
    handle = string()
    name = string()
    owner = string()
    dimaltd = integer()
    dimaltf = float()
    dimalttd = integer()
    dimasz = float()
    dimblk = string()
    dimblk1 = string()
    dimblk2 = string()
    dimcen = float()
    dimclrt = integer()
    dimdec = integer()
    dimdli = float()
    dimdsep = integer()
    dimexe = float()
    dimexo = float()
    dimgap = float()
    dimldrblk = string()
    dimtad = integer()
    dimtdec = integer()
    dimtih = integer()
    dimtofl = integer()
    dimtoh = integer()
    dimtolj = integer()
    dimtxsty = string()
    dimtxt = float()
    dimtzin = integer()
    dimzin = integer()

    def __init__(self, entity, meta_id):
        self.meta_id = meta_id
        self.dxftype = entity.dxf.dxftype
        self.flags = entity.dxf.flags
        self.handle = entity.dxf.handle
        self.name = entity.dxf.name
        self.owner = entity.dxf.owner
        self.dimaltd = entity.dxf.dimaltd
        self.dimaltf = entity.dxf.dimaltf
        self.dimalttd = entity.dxf.dimalttd
        self.dimasz = entity.dxf.dimasz
        self.dimblk = entity.dxf.dimblk
        self.dimblk1 = entity.dxf.dimblk1
        self.dimblk2 = entity.dxf.dimblk2
        self.dimcen = entity.dxf.dimcen
        self.dimclrt = entity.dxf.dimclrt
        self.dimdec = entity.dxf.dimdec
        self.dimdli = entity.dxf.dimdli
        self.dimdsep = entity.dxf.dimdsep
        self.dimexe = entity.dxf.dimexe
        self.dimexo = entity.dxf.dimexo
        self.dimgap = entity.dxf.dimgap
        self.dimldrblk = entity.dxf.dimldrblk
        self.dimtad = entity.dxf.dimtad
        self.dimtdec = entity.dxf.dimtdec
        self.dimtih = entity.dxf.dimtih
        self.dimtofl = entity.dxf.dimtofl
        self.dimtoh = entity.dxf.dimtoh
        self.dimtolj = entity.dxf.dimtolj
        self.dimtxsty = entity.dxf.dimtxsty
        self.dimtxt = entity.dxf.dimtxt
        self.dimtzin = entity.dxf.dimtzin
        self.dimzin = entity.dxf.dimzin

    def dxf(self):
        cont = dict()
        cont['dxf'] = dict()
        cont['dxf']['flags'] = self.flags
        cont['dxf']['name'] = self.name
        cont['dxf']['owner'] = self.owner
        cont['dxf']['dimaltd'] = self.dimaltd
        cont['dxf']['dimaltf'] = self.dimaltf
        cont['dxf']['dimalttd'] = self.dimalttd
        cont['dxf']['dimasz'] = self.dimasz
        cont['dxf']['dimblk'] = self.dimblk
        cont['dxf']['dimblk1'] = self.dimblk1
        cont['dxf']['dimblk2'] = self.dimblk2
        cont['dxf']['dimcen'] = self.dimcen
        cont['dxf']['dimclrt'] = self.dimclrt
        cont['dxf']['dimdec'] = self.dimdec
        cont['dxf']['dimdli'] = self.dimdli
        cont['dxf']['dimdsep'] = self.dimdsep
        cont['dxf']['dimexe'] = self.dimexe
        cont['dxf']['dimexo'] = self.dimexo
        cont['dxf']['dimgap'] = self.dimgap
        cont['dxf']['dimldrblk'] = self.dimldrblk
        cont['dxf']['dimtad'] = self.dimtad
        cont['dxf']['dimtdec'] = self.dimtdec
        cont['dxf']['dimtih'] = self.dimtih
        cont['dxf']['dimtofl'] = self.dimtofl
        cont['dxf']['dimtoh'] = self.dimtoh
        cont['dxf']['dimtolj'] = self.dimtolj
        cont['dxf']['dimtxsty'] = self.dimtxsty
        cont['dxf']['dimtxt'] = self.dimtxt
        cont['dxf']['dimtzin'] = self.dimtzin
        cont['dxf']['dimzin'] = self.dimzin
        return cont


class LinetypeModel(DXFModel):
    __tablename__ = 'linetype'

    name = string()
    owner = string()
    description = string()
    flags = integer()
    handle = string()
    is_complex_type = largebinary()
    pattern = largebinary()
    tags = largebinary()

    def __init__(self, entity=None, meta_id=None):
        self.meta_id = meta_id
        self.name = entity.dxf.name
        self.owner = entity.dxf.owner
        self.description = entity.dxf.description
        self.flags = entity.dxf.flags
        self.handle = entity.dxf.handle
        self.is_complex_type = pickle.dumps(entity.pattern_tags.is_complex_type())
        self.pattern = pickle.dumps(entity.pattern_tags.compile())
        self.tags = pickle.dumps(entity.pattern_tags)

    def dxf(self):
        cont = dict()
        cont['dxf'] = dict()
        cont['dxf']['name'] = self.name
        cont['dxf']['owner'] = self.owner
        cont['dxf']['description'] = self.description
        cont['dxf']['flags'] = self.flags
        cont['is_complex_type'] = largebinary_loads(self.is_complex_type)
        cont['pattern'] = largebinary_loads(self.pattern)
        cont['tags'] = largebinary_loads(self.tags)
        return cont


class ViewportModel(DXFModel):
    __tablename__ = 'viewport'

    ambient_color_aci = integer()
    ambient_true_color = integer()
    aspect_ratio = float()
    back_clipping = float()
    brightness = float()
    center = largebinary()
    circle_sides = integer()
    contrast = float()
    default_lighting_on = integer()
    default_lighting_type = integer()
    direction = largebinary()
    elevation = float()
    fast_zoom = integer()
    flags = integer()
    focal_length = float()
    front_clipping = float()
    grid_on = float()
    grid_spacing = largebinary()
    height = float()
    lower_left = largebinary()
    major_grid_lines = integer()
    owner = integer()
    render_mode = integer()
    snap_base = largebinary()
    snap_isopair = integer()
    snap_on = integer()
    snap_rotation = float()
    snap_spacing = largebinary()
    snap_style = integer()
    target = largebinary()
    ucs_icon = integer()
    ucs_origin = largebinary()
    ucs_ortho_type = integer()
    ucs_vp = integer()
    ucs_xaxis = largebinary()
    ucs_yaxis = largebinary()
    unknown1 = integer()
    upper_right = largebinary()
    view_mode = integer()
    view_twist = float()

    def __init__(self, dxf, meta_id):
        self.meta_id = meta_id
        self.ambient_color_aci = dxf.ambient_color_aci
        self.ambient_true_color = dxf.ambient_true_color
        self.aspect_ratio = dxf.aspect_ratio
        self.back_clipping = dxf.back_clipping
        self.brightness = dxf.brightness
        self.center = pickle.dumps(dxf.center)
        self.circle_sides = dxf.circle_sides
        self.contrast = dxf.contrast
        self.default_lighting_on = dxf.default_lighting_on
        self.default_lighting_type = dxf.default_lighting_type
        self.direction = pickle.dumps(dxf.direction)
        self.elevation = dxf.elevation
        self.fast_zoom = dxf.fast_zoom
        self.flags = dxf.flags
        self.focal_length = dxf.focal_length
        self.front_clipping = dxf.front_clipping
        self.grid_on = dxf.grid_on
        self.grid_spacing = pickle.dumps(dxf.grid_spacing)
        self.height = dxf.height
        self.lower_left = pickle.dumps(dxf.lower_left)
        self.major_grid_lines = dxf.major_grid_lines
        self.owner = dxf.owner
        self.render_mode = dxf.render_mode
        self.snap_base = pickle.dumps(dxf.snap_base)
        self.snap_isopair = dxf.snap_isopair
        self.snap_on = dxf.snap_on
        self.snap_rotation = dxf.snap_rotation
        self.snap_spacing = pickle.dumps(dxf.snap_spacing)
        self.snap_style = dxf.snap_style
        self.target = pickle.dumps(dxf.target)
        self.ucs_icon = dxf.ucs_icon
        self.ucs_origin = pickle.dumps(dxf.ucs_origin)
        self.ucs_ortho_type = dxf.ucs_ortho_type
        self.ucs_vp = dxf.ucs_vp
        self.ucs_xaxis = pickle.dumps(dxf.ucs_xaxis)
        self.ucs_yaxis = pickle.dumps(dxf.ucs_yaxis)
        self.unknown1 = dxf.unknown1
        self.upper_right = pickle.dumps(dxf.upper_right)
        self.view_mode = dxf.view_mode
        self.view_twist = dxf.view_twist

    def dxf(self):
        cont = dict()
        return cont

    def dxf_viewport(self, viewport):
        viewport.ambient_color_aci = self.ambient_color_aci
        viewport.ambient_true_color = self.ambient_true_color
        viewport.aspect_ratio = self.aspect_ratio
        viewport.back_clipping = self.back_clipping
        viewport.brightness = self.brightness
        viewport.center = largebinary_loads(self.center)
        viewport.circle_sides = self.circle_sides
        viewport.contrast = self.contrast
        viewport.default_lighting_on = self.default_lighting_on
        viewport.default_lighting_type = self.default_lighting_type
        viewport.direction = largebinary_loads(self.direction)
        viewport.elevation = self.elevation
        viewport.fast_zoom = self.fast_zoom
        viewport.flags = self.flags
        viewport.focal_length = self.focal_length
        viewport.front_clipping = self.front_clipping
        viewport.grid_on = self.grid_on
        viewport.grid_spacing = largebinary_loads(self.grid_spacing)
        viewport.height = self.height
        viewport.lower_left = largebinary_loads(self.lower_left)
        viewport.major_grid_lines = self.major_grid_lines
        viewport.owner = self.owner
        viewport.render_mode = self.render_mode
        viewport.snap_base = largebinary_loads(self.snap_base)
        viewport.snap_isopair = self.snap_isopair
        viewport.snap_on = self.snap_on
        viewport.snap_rotation = self.snap_rotation
        viewport.snap_spacing = largebinary_loads(self.snap_spacing)
        viewport.snap_style = self.snap_style
        viewport.target = largebinary_loads(self.target)
        viewport.ucs_icon = self.ucs_icon
        viewport.ucs_origin = largebinary_loads(self.ucs_origin)
        viewport.ucs_ortho_type = self.ucs_ortho_type
        viewport.ucs_vp = self.ucs_vp
        viewport.ucs_xaxis = largebinary_loads(self.ucs_xaxis)
        viewport.ucs_yaxis = largebinary_loads(self.ucs_yaxis)
        viewport.unknown1 = self.unknown1
        viewport.upper_right = largebinary_loads(self.upper_right)
        viewport.view_mode = self.view_mode
        viewport.view_twist = self.view_twist


class LayoutModel(DXFModel):
    __tablename__ = 'layout'

    owner = string()
    insert_base = largebinary()
    handle = string()
    block_record_handle = string()
    current_style_sheet = string()
    dxftype = string()
    elevation = float()
    limmax = largebinary()
    limmin = largebinary()
    extmax = largebinary()
    extmin = largebinary()
    layout_flags = integer()
    page_setup_name = string()
    paper_height = float()
    paper_image_origin_x = float()
    paper_image_origin_y = float()
    paper_size = string()
    paper_width = float()
    plot_configuration_file = string()
    plot_layout_flags = integer()
    plot_origin_x_offset = float()
    plot_origin_y_offset = float()
    plot_paper_units = integer()
    plot_rotation = integer()
    plot_type = integer()
    plot_view_name = string()
    plot_window_x1 = float()
    plot_window_x2 = float()
    plot_window_y1 = float()
    plot_window_y2 = float()
    left_margin = float()
    right_margin = float()
    top_margin = float()
    bottom_margin = float()
    scale_denominator = float()
    scale_numerator = float()
    shade_plot_custom_dpi = integer()
    shade_plot_mode = integer()
    shade_plot_resolution_level = integer()
    standard_scale_type = integer()
    taborder = integer()
    ucs_origin = largebinary()
    ucs_type = integer()
    ucs_xaxis = largebinary()
    ucs_yaxis = largebinary()
    unit_factor = float()
    viewport_handle = string()

    def __init__(self, dxf, meta_id):
        self.meta_id = meta_id
        self.owner = dxf.owner
        p = [dxf.insert_base.x, dxf.insert_base.y]
        self.insert_base = largebinary_dumps(p)
        self.handle = dxf.handle
        self.block_record_handle = dxf.block_record_handle
        self.current_style_sheet = dxf.current_style_sheet
        self.dxftype = dxf.dxftype
        self.elevation = dxf.elevation
        p = [dxf.limmax.x, dxf.limmax.y]
        self.limmax = largebinary_dumps(p)
        p = [dxf.limmin.x, dxf.limmin.y]
        self.limmin = largebinary_dumps(p)
        p = [dxf.extmax.x, dxf.extmax.y]
        self.extmax = largebinary_dumps(p)
        p = [dxf.extmin.x, dxf.extmin.y]
        self.extmin = largebinary_dumps(p)
        self.layout_flags = dxf.layout_flags
        self.page_setup_name = dxf.page_setup_name
        self.paper_height = dxf.paper_height
        self.paper_image_origin_x = dxf.paper_image_origin_x
        self.paper_image_origin_y = dxf.paper_image_origin_y
        self.paper_size = dxf.paper_size
        self.paper_width = dxf.paper_width
        self.plot_configuration_file = dxf.plot_configuration_file
        self.plot_layout_flags = dxf.plot_layout_flags
        self.plot_origin_x_offset = dxf.plot_origin_x_offset
        self.plot_origin_y_offset = dxf.plot_origin_y_offset
        self.plot_paper_units = dxf.plot_paper_units
        self.plot_rotation = dxf.plot_rotation
        self.plot_type = dxf.plot_type
        self.plot_view_name = dxf.plot_view_name
        self.plot_window_x1 = dxf.plot_window_x1
        self.plot_window_x2 = dxf.plot_window_x2
        self.plot_window_y1 = dxf.plot_window_y1
        self.plot_window_y2 = dxf.plot_window_y2
        self.left_margin = dxf.left_margin
        self.right_margin = dxf.right_margin
        self.top_margin = dxf.top_margin
        self.bottom_margin = dxf.bottom_margin
        self.scale_denominator = dxf.scale_denominator
        self.scale_numerator = dxf.scale_numerator
        self.shade_plot_custom_dpi = dxf.shade_plot_custom_dpi
        self.shade_plot_mode = dxf.shade_plot_mode
        self.shade_plot_resolution_level = dxf.shade_plot_resolution_level
        self.standard_scale_type = dxf.standard_scale_type
        self.taborder = dxf.taborder
        p = [dxf.ucs_origin.x, dxf.ucs_origin.y]
        self.ucs_origin = largebinary_dumps(p)
        self.ucs_type = dxf.ucs_type
        p = [dxf.ucs_xaxis.x, dxf.ucs_xaxis.y]
        self.ucs_xaxis = largebinary_dumps(p)
        p = [dxf.ucs_yaxis.x, dxf.ucs_yaxis.y]
        self.ucs_yaxis = largebinary_dumps(p)
        self.unit_factor = dxf.unit_factor
        self.viewport_handle = dxf.viewport_handle

    def dxf(self):
        pass

    def dxf_layout(self, layout):
        layout.set_dxf_attrib('owner', self.owner)
        layout.set_dxf_attrib('insert_base', largebinary_loads(self.insert_base))
        layout.set_dxf_attrib('current_style_sheet', self.current_style_sheet)
        layout.set_dxf_attrib('elevation', self.elevation)
        layout.set_dxf_attrib('limmax', largebinary_loads(self.limmax))
        layout.set_dxf_attrib('limmin', largebinary_loads(self.limmin))
        layout.set_dxf_attrib('extmax', largebinary_loads(self.extmax))
        layout.set_dxf_attrib('extmin', largebinary_loads(self.extmin))
        layout.set_dxf_attrib('layout_flags', self.layout_flags)
        layout.set_dxf_attrib('page_setup_name', self.page_setup_name)
        layout.set_dxf_attrib('paper_height', self.paper_height)
        layout.set_dxf_attrib('paper_image_origin_x', self.paper_image_origin_x)
        layout.set_dxf_attrib('paper_image_origin_y', self.paper_image_origin_y)
        layout.set_dxf_attrib('paper_size', self.paper_size)
        layout.set_dxf_attrib('paper_width', self.paper_width)
        layout.set_dxf_attrib('plot_configuration_file', self.plot_configuration_file)
        layout.set_dxf_attrib('plot_layout_flags', self.plot_layout_flags)
        layout.set_dxf_attrib('plot_origin_x_offset', self.plot_origin_x_offset)
        layout.set_dxf_attrib('plot_origin_y_offset', self.plot_origin_y_offset)
        layout.set_dxf_attrib('plot_paper_units', self.plot_paper_units)
        layout.set_dxf_attrib('plot_rotation', self.plot_rotation)
        layout.set_dxf_attrib('plot_type', self.plot_type)
        layout.set_dxf_attrib('plot_view_name', self.plot_view_name)
        layout.set_dxf_attrib('plot_window_x1', self.plot_window_x1)
        layout.set_dxf_attrib('plot_window_x2', self.plot_window_x2)
        layout.set_dxf_attrib('plot_window_y1', self.plot_window_y1)
        layout.set_dxf_attrib('plot_window_y2', self.plot_window_y2)
        layout.set_dxf_attrib('left_margin', self.left_margin)
        layout.set_dxf_attrib('right_margin', self.right_margin)
        layout.set_dxf_attrib('top_margin', self.top_margin)
        layout.set_dxf_attrib('bottom_margin', self.bottom_margin)
        layout.set_dxf_attrib('scale_denominator', self.scale_denominator)
        layout.set_dxf_attrib('scale_numerator', self.scale_numerator)
        layout.set_dxf_attrib('shade_plot_custom_dpi', self.shade_plot_custom_dpi)
        layout.set_dxf_attrib('shade_plot_mode', self.shade_plot_mode)
        layout.set_dxf_attrib('shade_plot_resolution_level', self.shade_plot_resolution_level)
        layout.set_dxf_attrib('standard_scale_type', self.standard_scale_type)
        layout.set_dxf_attrib('taborder', self.taborder)
        layout.set_dxf_attrib('ucs_origin', largebinary_loads(self.ucs_origin))
        layout.set_dxf_attrib('ucs_type', self.ucs_type)
        layout.set_dxf_attrib('ucs_xaxis', largebinary_loads(self.ucs_xaxis))
        layout.set_dxf_attrib('ucs_yaxis', largebinary_loads(self.ucs_yaxis))
        layout.set_dxf_attrib('unit_factor', self.unit_factor)
        layout.set_dxf_attrib('viewport_handle', self.viewport_handle)


class LWPolylineModel(EntityModel):
    __tablename__ = 'lwpolyline'

    points = longblob()
    elevation = float()
    flags = integer()
    const_width = float()
    count = integer()
    closed = largebinary()

    def init(self, entity):
        l, r, t, b = None, None, None, None
        with entity.points("xy") as points:
            for p in points:
                l, r, t, b = box(l, r, t, b, p)
            self.points = largebinary_dumps(points)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)
        self.x, self.y = (l + r) / 2, (t + b) / 2
        self.elevation = entity.dxf.elevation
        self.flags = entity.dxf.flags
        self.const_width = entity.dxf.const_width
        self.count = entity.dxf.count
        self.closed = pickle.dumps(entity.closed)

    def dxf(self):
        cont = super().dxf()
        cont['points'] = largebinary_loads(self.points)
        cont['dxf']['elevation'] = self.elevation
        cont['dxf']['flags'] = self.flags
        cont['dxf']['const_width'] = self.const_width
        cont['closed'] = largebinary_loads(self.closed)
        # cont['dxf']['linetype'] = self.linetype
        cont['dxf']['lineweight'] = self.lineweight
        return cont

    def vector(self):
        cont = super().vector()
        cont['points'] = largebinary_loads(self.points)
        cont['width'] = self.const_width
        cont['closed'] = largebinary_loads(self.closed)
        return cont


class TextModel(EntityModel):
    __tablename__ = 'text'

    text = string()
    insert = largebinary()
    align_point = largebinary()
    height = float()
    rotation = float()
    oblique = float()
    style = string(default='Standard')
    width = float(default=1)
    halign = integer()
    valign = integer()
    text_generation_flag = integer()

    def init(self, entity):
        self.text = entity.dxf.text
        self.x, self.y = entity.dxf.insert.x, entity.dxf.insert.y
        self.left, self.right = math.floor(self.x), math.ceil(self.x)
        self.top, self.bottom = math.ceil(self.y), math.floor(self.y)
        self.insert = largebinary_dumps([self.x, self.y])
        if self.align_point is not None:
            p = [entity.dxf.align_point.x, entity.dxf.align_point.y]
            self.align_point = largebinary_dumps(p)
        self.height = entity.dxf.height
        self.rotation = entity.dxf.rotation
        self.oblique = entity.dxf.oblique
        self.style = entity.dxf.style
        self.width = entity.dxf.width
        self.halign = entity.dxf.halign
        self.valign = entity.dxf.valign
        self.text_generation_flag = entity.dxf.text_generation_flag

    def dxf(self):
        cont = super().dxf()
        cont['text'] = self.text
        cont['dxf']['text'] = self.text
        cont['dxf']['insert'] = largebinary_loads(self.insert)
        cont['dxf']['align_point'] = None if self.align_point is None else largebinary_loads(self.align_point)
        cont['dxf']['height'] = self.height
        cont['dxf']['rotation'] = self.rotation
        cont['dxf']['oblique'] = self.oblique
        # cont['dxf']['style'] = self.style
        cont['dxf']['width'] = self.width
        # cont['dxf']['halign'] = self.halign
        # cont['dxf']['valign'] = self.valign
        cont['dxf']['text_generation_flag'] = self.text_generation_flag
        return cont

    def vector(self):
        cont = super().vector()
        cont['text'] = self.text
        cont['point'] = largebinary_loads(self.insert)
        cont['height'] = self.height
        cont['rotation'] = self.rotation
        cont['style'] = self.style
        cont['width'] = self.width
        return cont


class InsertModel(EntityModel):
    __tablename__ = 'insert'

    name = string()
    insert = largebinary()
    base = largebinary()
    xscale = float()
    yscale = float()
    zscale = float()
    rotation = float()
    row_count = integer()
    row_spacing = float()
    column_count = integer()
    column_spacing = float()
    mcount = integer()

    def init(self, entity):
        self.name = entity.dxf.name
        self.x, self.y = entity.dxf.insert.x, entity.dxf.insert.y
        self.left, self.right = math.floor(self.x), math.ceil(self.x)
        self.top, self.bottom = math.ceil(self.y), math.floor(self.y)
        self.insert = largebinary_dumps([self.x, self.y])
        self.xscale = entity.dxf.xscale
        self.yscale = entity.dxf.yscale
        self.zscale = entity.dxf.zscale
        self.rotation = entity.dxf.rotation
        self.row_count = entity.dxf.row_count
        self.row_spacing = entity.dxf.row_spacing
        self.column_count = entity.dxf.column_count
        self.column_spacing = entity.dxf.column_spacing

    def dxf(self):
        cont = super().dxf()
        cont['dxf']['name'] = self.name
        cont['dxf']['insert'] = largebinary_loads(self.insert)
        cont['dxf']['xscale'] = self.xscale
        cont['dxf']['yscale'] = self.yscale
        cont['dxf']['zscale'] = self.zscale
        cont['dxf']['rotation'] = self.rotation
        cont['dxf']['row_count'] = self.row_count
        cont['dxf']['row_spacing'] = self.row_spacing
        cont['dxf']['column_count'] = self.column_count
        cont['dxf']['column_spacing'] = self.column_spacing
        cont['base'] = largebinary_loads(self.base)
        return cont

    def vector(self):
        cont = super().vector()
        cont['insert_id'] = self.insert_id
        cont['xscale'] = self.xscale
        cont['yscale'] = self.yscale
        cont['zscale'] = self.zscale
        cont['rotation'] = self.rotation
        cont['row_count'] = self.row_count
        cont['row_spacing'] = self.row_spacing
        cont['column_count'] = self.column_count
        cont['column_spacing'] = self.column_spacing
        cont['name'] = self.name
        cont['point'] = largebinary_loads(self.insert)
        cont['base'] = largebinary_loads(self.base)
        return cont


class LineModel(EntityModel):
    __tablename__ = 'line'

    start = largebinary()
    end = largebinary()
    thickness = float()
    extrusion = largebinary()

    def init(self, entity):
        l, r, t, b = None, None, None, None
        p = [entity.dxf.start.x, entity.dxf.start.y]
        l, r, t, b = box(l, r, t, b, p)
        self.start = largebinary_dumps(p)
        p = [entity.dxf.end.x, entity.dxf.end.y]
        self.end = largebinary_dumps(p)
        l, r, t, b = box(l, r, t, b, p)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)
        self.x, self.y = (l + r) / 2, (t + b) / 2
        self.thickness = entity.dxf.thickness
        self.extrusion = pickle.dumps(entity.dxf.extrusion)

    def dxf(self):
        cont = super().dxf()
        cont['start'] = largebinary_loads(self.start)
        cont['end'] = largebinary_loads(self.end)
        cont['dxf']['thickness'] = self.thickness
        cont['dxf']['extrusion'] = largebinary_loads(self.extrusion)
        # cont['dxf']['linetype'] = self.linetype
        cont['dxf']['lineweight'] = self.lineweight
        return cont

    def vector(self):
        cont = super().vector()
        cont['start'] = largebinary_loads(self.start)
        cont['end'] = largebinary_loads(self.end)
        return cont


class MTextModel(EntityModel):
    __tablename__ = 'mtext'

    text = string()
    insert = largebinary()
    char_height = float(default=1.0)
    width = float()
    attachment_point = integer(default=1)
    flow_direction = integer(default=1)
    style = string(default='Standard')
    text_direction = largebinary()
    rotation = float()
    line_spacing_style = integer(default=1)
    line_spacing_factor = integer(default=1)
    bg_fill = integer()
    box_fill_scale = largebinary()
    bg_fill_color = largebinary()
    bg_fill_true_color = largebinary()
    bg_fill_color_name = largebinary()
    transparency = largebinary()

    def init(self, entity):
        self.text = entity.text
        self.x, self.y = entity.dxf.insert.x, entity.dxf.insert.y
        self.left, self.right = math.floor(self.x), math.ceil(self.x)
        self.top, self.bottom = math.ceil(self.y), math.floor(self.y)
        self.insert = largebinary_dumps([self.x, self.y])
        self.char_height = entity.dxf.char_height
        self.width = entity.dxf.width
        self.attachment_point = entity.dxf.attachment_point
        self.flow_direction = entity.dxf.flow_direction
        self.style = entity.dxf.style
        self.text_direction = pickle.dumps(entity.dxf.text_direction)
        self.rotation = entity.get_rotation()
        self.line_spacing_style = entity.dxf.line_spacing_style
        self.line_spacing_factor = entity.dxf.line_spacing_factor
        # self.bg_fill = entity.dxf.bg_fill
        # self.box_fill_scale = pickle.dumps(entity.dxf.box_fill_scale)
        # self.bg_fill_color = pickle.dumps(entity.dxf.bg_fill_color)
        # self.bg_fill_true_color = pickle.dumps(entity.dxf.bg_fill_true_color)
        # self.bg_fill_color_name = pickle.dumps(entity.dxf.bg_fill_color_name)
        # self.transparency = pickle.dumps(entity.dxf.transparency)

    def dxf(self):
        cont = super().dxf()
        cont['text'] = self.text
        cont['dxf']['insert'] = largebinary_loads(self.insert)
        cont['dxf']['char_height'] = self.char_height
        cont['dxf']['width'] = self.width
        cont['dxf']['attachment_point'] = self.attachment_point
        cont['dxf']['flow_direction'] = self.flow_direction
        # cont['dxf']['style'] = self.style
        cont['dxf']['text_direction'] = largebinary_loads(self.text_direction)
        cont['dxf']['rotation'] = self.rotation
        cont['dxf']['line_spacing_style'] = self.line_spacing_style
        cont['dxf']['line_spacing_factor'] = self.line_spacing_factor
        # cont['dxf']['bg_fill'] = self.bg_fill
        # cont['dxf']['box_fill_scale'] = largebinary_loads(self.box_fill_scale)
        # cont['dxf']['bg_fill_color'] = largebinary_loads(self.bg_fill_color)
        # cont['dxf']['bg_fill_true_color'] = largebinary_loads(self.bg_fill_true_color)
        # cont['dxf']['bg_fill_color_name'] = largebinary_loads(self.bg_fill_color_name)
        # cont['dxf']['transparency'] = largebinary_loads(self.transparency)
        return cont

    def vector(self):
        cont = super().vector()
        cont['text'] = ''
        arrs = self.text.strip('{').strip('}').split('\\f')
        for arr in arrs:
            cont['text'] += arr.split(';')[-1]
        cont['point'] = largebinary_loads(self.insert)
        cont['char_height'] = self.char_height
        cont['width'] = self.width
        cont['flow_direction'] = self.flow_direction
        cont['style'] = self.style
        # cont['text_direction'] = largebinary_loads(self.text_direction)
        cont['rotation'] = self.rotation
        cont['line_spacing_style'] = self.line_spacing_style
        cont['line_spacing_factor'] = self.line_spacing_factor
        return cont


class EllipseModel(EntityModel):
    __tablename__ = 'ellipse'

    center = largebinary()
    major_axis = largebinary()
    minor_axis = largebinary()
    ratio = float(default=1.0)
    start_param = float()
    end_param = float()

    def init(self, entity):
        self.x, self.y = entity.dxf.center.x, entity.dxf.center.y
        self.center = largebinary_dumps([self.x, self.y])
        self.major_axis = pickle.dumps(entity.dxf.major_axis)
        self.minor_axis = pickle.dumps(entity.minor_axis)
        self.ratio = entity.dxf.ratio
        self.start_param = entity.dxf.start_param
        self.end_param = entity.dxf.end_param
        x, y = self.x, self.y
        ux, uy = entity.dxf.major_axis[0], entity.dxf.major_axis[1]
        vx, vy = entity.minor_axis[0], entity.minor_axis[1]
        points = ellipse(x, y, ux, uy, vx, vy, self.start_param, self.end_param)
        l, r, t, b = None, None, None, None
        for p in points:
            l, r, t, b = box(l, r, t, b, p)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)

    def dxf(self):
        cont = super().dxf()
        cont['center'] = largebinary_loads(self.center)
        cont['major_axis'] = largebinary_loads(self.major_axis)
        cont['minor_axis'] = largebinary_loads(self.minor_axis)
        cont['ratio'] = self.ratio
        cont['start_param'] = self.start_param
        cont['end_param'] = self.end_param
        return cont

    def vector(self):
        cont = super().vector()
        cont['center'] = largebinary_loads(self.center)
        cont['major_axis'] = vec3arr(largebinary_loads(self.major_axis))
        cont['minor_axis'] = vec3arr(largebinary_loads(self.minor_axis))
        cont['ratio'] = self.ratio
        cont['start_param'] = self.start_param
        cont['end_param'] = self.end_param
        return cont


class HatchModel(EntityModel):
    __tablename__ = 'hatch'

    pattern_name = string(default='Standard')
    solid_fill = integer(default=1)
    associative = integer()
    hatch_style = integer()
    pattern_type = integer()
    pattern_angle = float()
    pattern_scale = float()
    pattern_double = integer()
    n_seed_points = integer()
    elevation = largebinary()
    paths = longblob()
    pattern = largebinary()
    gradient = largebinary()
    seeds = largebinary()
    bgcolor = largebinary()

    def init(self, entity):
        self.pattern_name = entity.dxf.pattern_name
        self.solid_fill = entity.dxf.solid_fill
        self.associative = entity.dxf.associative
        self.hatch_style = entity.dxf.hatch_style
        self.pattern_type = entity.dxf.pattern_type
        self.pattern_angle = entity.dxf.pattern_angle
        self.pattern_scale = entity.dxf.pattern_scale
        self.pattern_double = entity.dxf.pattern_double
        self.n_seed_points = entity.dxf.n_seed_points
        self.elevation = pickle.dumps(entity.dxf.elevation)
        self.paths = pickle.dumps(entity.paths)
        self.pattern = pickle.dumps(entity.pattern)
        self.gradient = pickle.dumps(entity.gradient)
        self.seeds = pickle.dumps(entity.seeds)
        self.bgcolor = pickle.dumps(entity.bgcolor)
        l, r, t, b = None, None, None, None
        for path in entity.paths:
            name = type(path).__name__
            if name == 'PolylinePath':
                for p in path.vertices:
                    l, r, t, b = box(l, r, t, b, (p[0], p[1]))
            else:
                for e in path.edges:
                    edge_type = e.EDGE_TYPE
                    if edge_type == 'LineEdge':
                        l, r, t, b = box(l, r, t, b, (e.start[0], e.start[1]))
                        l, r, t, b = box(l, r, t, b, (e.end[0], e.end[1]))
                    elif edge_type == 'ArcEdge':
                        points = arc(e.center[0], e.center[1], e.radius, e.start_angle, e.end_angle)
                        for p in points:
                            l, r, t, b = box(l, r, t, b, p)
                    elif edge_type == 'SplineEdge':
                        for p in e.control_points:
                            l, r, t, b = box(l, r, t, b, (p[0], p[1]))
                    elif edge_type == 'EllipseEdge':
                        minor_axiss = minor_axis(e.major_axis, Vec3(0, 0, 1), e.ratio)
                        x, y = e.center[0], e.center[1]
                        ux, uy = e.major_axis[0], e.major_axis[1]
                        vx, vy = minor_axiss[0], minor_axiss[1]
                        points = ellipse(x, y, ux, uy, vx, vy, e.start_param, e.end_param)
                        for p in points:
                            l, r, t, b = box(l, r, t, b, p)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)
        self.x, self.y = (l + r) / 2, (t + b) / 2

    def dxf(self):
        cont = super().dxf()
        cont['dxf']['pattern_name'] = self.pattern_name
        cont['dxf']['solid_fill'] = self.solid_fill
        cont['dxf']['associative'] = self.associative
        cont['dxf']['hatch_style'] = self.hatch_style
        cont['dxf']['pattern_type'] = self.pattern_type
        cont['dxf']['pattern_angle'] = self.pattern_angle
        cont['dxf']['pattern_scale'] = self.pattern_scale
        cont['dxf']['pattern_double'] = self.pattern_double
        cont['dxf']['n_seed_points'] = self.n_seed_points
        cont['dxf']['elevation'] = largebinary_loads(self.elevation)
        cont['paths'] = largebinary_loads(self.paths)
        cont['pattern'] = largebinary_loads(self.pattern)
        cont['gradient'] = largebinary_loads(self.gradient)
        cont['seeds'] = largebinary_loads(self.seeds)
        cont['bgcolor'] = largebinary_loads(self.bgcolor)
        return cont

    def vector(self):
        cont = super().vector()
        cont['pattern_name'] = self.pattern_name
        cont['solid_fill'] = self.solid_fill
        cont['associative'] = self.associative
        cont['hatch_style'] = self.hatch_style
        cont['pattern_type'] = self.pattern_type
        cont['pattern_angle'] = self.pattern_angle
        cont['pattern_scale'] = self.pattern_scale
        cont['pattern_double'] = self.pattern_double
        cont['pattern_double'] = self.pattern_double
        cont['n_seed_points'] = self.n_seed_points
        cont['elevation'] = (0, 0, 0)
        cont['paths'], paths = [], largebinary_loads(self.paths)
        for path in paths:
            name = type(path).__name__
            if name == 'PolylinePath':
                polyline_path = {
                    'path_type': 'PolylinePath',
                    'is_closed': path.is_closed,
                    'polylines': [[i[0], i[1]] for i in path.vertices]
                }
                cont['paths'].append(polyline_path)
            else:
                edge_path = {
                    'path_type': 'EdgePath',
                    'edges': []
                }
                for e in path.edges:
                    edge_type = e.EDGE_TYPE
                    edge = {'edge_type': edge_type}
                    if edge_type == 'LineEdge':
                        edge['start'] = [e.start[0], e.start[1]]
                        edge['end'] = [e.end[0], e.end[1]]
                    elif edge_type == 'ArcEdge':
                        edge['center'] = [e.center[0], e.center[1]]
                        edge['start_angle'] = e.start_angle
                        edge['end_angle'] = e.end_angle
                        edge['radius'] = e.radius
                    elif edge_type == 'SplineEdge':
                        edge['control_points'] = [[i[0], i[1]] for i in e.control_points]
                    elif edge_type == 'EllipseEdge':
                        edge['center'] = [e.center[0], e.center[1]]
                        edge['major_axis'] = [e.major_axis[0], e.major_axis[1]]
                        edge['start_angle'] = e.start_angle
                        edge['end_angle'] = e.end_angle
                        edge['start_param'] = e.start_param
                        edge['end_param'] = e.end_param
                        edge['start_point'] = [e.start_point[0], e.start_point[1]]
                        edge['end_point'] = [e.end_point[0], e.end_point[1]]
                        edge['ratio'] = e.ratio
                        minor_axiss = minor_axis(e.major_axis, Vec3(0, 0, 1), e.ratio)
                        edge['minor_axis'] = [minor_axiss[0], minor_axiss[1]]
                    edge_path['edges'].append(edge)
                cont['paths'].append(edge_path)
        return cont


class CircleModel(EntityModel):
    __tablename__ = 'circle'

    center = largebinary()
    radius = float()

    def init(self, entity):
        self.x, self.y = entity.dxf.center.x, entity.dxf.center.y
        self.center = largebinary_dumps([self.x, self.y])
        self.radius = entity.dxf.radius
        points = arc(self.x, self.y, self.radius)
        l, r, t, b = None, None, None, None
        for p in points:
            l, r, t, b = box(l, r, t, b, p)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)

    def dxf(self):
        cont = super().dxf()
        cont['center'] = largebinary_loads(self.center)
        cont['radius'] = self.radius
        return cont

    def vector(self):
        cont = super().vector()
        cont['center'] = largebinary_loads(self.center)
        cont['radius'] = self.radius
        return cont


class ArcModel(EntityModel):
    __tablename__ = 'arc'

    center = largebinary()
    radius = float()
    start_angle = float()
    end_angle = float()

    def init(self, entity):
        self.x, self.y = entity.dxf.center.x, entity.dxf.center.y
        self.center = largebinary_dumps([self.x, self.y])
        self.radius = entity.dxf.radius
        self.start_angle = entity.dxf.start_angle
        self.end_angle = entity.dxf.end_angle
        points = arc(self.x, self.y, self.radius, self.start_angle, self.end_angle)
        l, r, t, b = None, None, None, None
        for p in points:
            l, r, t, b = box(l, r, t, b, p)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)

    def dxf(self):
        cont = super().dxf()
        cont['center'] = largebinary_loads(self.center)
        cont['radius'] = self.radius
        cont['start_angle'] = self.start_angle
        cont['end_angle'] = self.end_angle
        return cont

    def vector(self):
        cont = super().vector()
        cont['center'] = largebinary_loads(self.center)
        cont['radius'] = self.radius
        cont['start_angle'] = self.start_angle
        cont['end_angle'] = self.end_angle
        return cont


class SplineModel(EntityModel):
    __tablename__ = 'spline'

    degree = integer()
    flags = integer()
    n_knots = integer()
    n_fit_points = integer()
    n_control_points = integer()
    knot_tolerance = float()
    fit_tolerance = float()
    control_point_tolerance = float()
    start_tangent = largebinary()
    end_tangent = largebinary()
    control_points = largebinary()
    fit_points = largebinary()
    knots = largebinary()
    weights = largebinary()
    closed = largebinary()

    def init(self, entity):
        self.degree = entity.dxf.degree
        self.flags = entity.dxf.flags
        self.n_knots = entity.dxf.n_knots
        self.n_fit_points = entity.dxf.n_fit_points
        self.n_control_points = entity.dxf.n_control_points
        self.knot_tolerance = entity.dxf.knot_tolerance
        self.fit_tolerance = entity.dxf.fit_tolerance
        self.control_point_tolerance = entity.dxf.control_point_tolerance
        l, r, t, b = None, None, None, None
        points = []
        for item in entity.control_points:
            p = (item[0], item[1])
            l, r, t, b = box(l, r, t, b, p)
            points.append(p)
        if len(points) > 0:
            self.control_points = largebinary_dumps(points)
        points = []
        for item in entity.fit_points:
            p = (item[0], item[1])
            l, r, t, b = box(l, r, t, b, p)
            points.append(p)
        if len(points) > 0:
            self.fit_points = largebinary_dumps(points)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)
        self.x, self.y = (l + r) / 2, (t + b) / 2
        self.knots = pickle.dumps(entity.knots)
        self.weights = pickle.dumps(entity.weights)
        self.closed = pickle.dumps(entity.closed)

    def dxf(self):
        cont = super().dxf()
        cont['dxf']['degree'] = self.degree
        cont['dxf']['flags'] = self.flags
        cont['n_knots'] = self.n_knots
        cont['n_fit_points'] = self.n_fit_points
        cont['n_control_points'] = self.n_control_points
        cont['dxf']['knot_tolerance'] = self.knot_tolerance
        cont['dxf']['fit_tolerance'] = self.fit_tolerance
        cont['dxf']['control_point_tolerance'] = self.control_point_tolerance
        cont['control_points'] = largebinary_loads(self.control_points) if self.control_points else None
        cont['fit_points'] = largebinary_loads(self.fit_points) if self.fit_points else None
        knots = largebinary_loads(self.knots)
        cont['knots'] = knots if len(knots) > 0 else None
        weights = largebinary_loads(self.weights)
        cont['weights'] = weights if len(weights) > 0 else None
        cont['closed'] = largebinary_loads(self.closed)
        return cont

    def vector(self):
        cont = super().vector()
        cont['closed'] = largebinary_loads(self.closed)
        cont['control_points'] = largebinary_loads(self.control_points) if self.control_points else None
        return cont


class SolidModel(EntityModel):
    __tablename__ = 'solid'

    vtx0 = largebinary()
    vtx1 = largebinary()
    vtx2 = largebinary()
    vtx3 = largebinary()

    def init(self, entity=None):
        self.left, self.right, self.top, self.bottom = 0, 0, 0, 0
        self.x, self.y = 0, 0
        self.vtx0 = pickle.dumps(entity.dxf.vtx0)
        self.vtx1 = pickle.dumps(entity.dxf.vtx1)
        self.vtx2 = pickle.dumps(entity.dxf.vtx2)
        self.vtx3 = pickle.dumps(entity.dxf.vtx3)

    def dxf(self):
        cont = super().dxf()
        cont['dxf']['vtx0'] = largebinary_loads(self.vtx0)
        cont['dxf']['vtx1'] = largebinary_loads(self.vtx1)
        cont['dxf']['vtx2'] = largebinary_loads(self.vtx2)
        cont['dxf']['vtx3'] = largebinary_loads(self.vtx3)
        return cont

    def vector(self):
        cont = super().vector()
        cont['vtx0'] = largebinary_loads(self.vtx0)
        cont['vtx1'] = largebinary_loads(self.vtx1)
        cont['vtx2'] = largebinary_loads(self.vtx2)
        cont['vtx3'] = largebinary_loads(self.vtx3)
        return cont


class PointModel(EntityModel):
    __tablename__ = 'point'

    location = largebinary()
    angle = float()

    def init(self, entity):
        self.x, self.y = entity.dxf.location.x, entity.dxf.location.y
        self.left, self.right = math.floor(self.x), math.ceil(self.x)
        self.top, self.bottom = math.ceil(self.y), math.floor(self.y)
        self.location = largebinary_dumps([self.x, self.y])
        self.angle = entity.dxf.angle

    def dxf(self):
        cont = super().dxf()
        cont['dxf']['location'] = largebinary_loads(self.location)
        cont['dxf']['angle'] = self.angle
        return cont

    def vector(self):
        cont = super().vector()
        cont['location'] = largebinary_loads(self.location)
        cont['angle'] = self.angle
        return cont


class PolylineModel(EntityModel):
    __tablename__ = 'polyline'

    elevation = largebinary()
    flags = integer()
    default_start_width = float()
    default_end_width = float()
    m_count = integer()
    n_count = integer()
    m_smooth_density = integer()
    n_smooth_density = integer()
    smooth_type = integer()
    vertices = largebinary()
    is_2d_polyline = largebinary()
    is_3d_polyline = largebinary()
    is_polygon_mesh = largebinary()
    is_poly_face_mesh = largebinary()
    is_closed = largebinary()
    is_m_closed = largebinary()
    is_n_closed = largebinary()
    has_arc = largebinary()
    has_width = largebinary()
    mode = string(default=0)

    def init(self, entity):
        l, r, t, b = None, None, None, None
        for v in entity.vertices:
            l, r, t, b = box(l, r, t, b, v.dxf.location.vec2)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)
        self.x, self.y = (l + r) / 2, (t + b) / 2
        self.elevation = pickle.dumps(entity.dxf.elevation)
        self.flags = entity.dxf.flags
        self.default_start_width = entity.dxf.default_start_width
        self.default_end_width = entity.dxf.default_end_width
        self.m_count = entity.dxf.m_count
        self.n_count = entity.dxf.n_count
        self.m_smooth_density = entity.dxf.m_smooth_density
        self.n_smooth_density = entity.dxf.n_smooth_density
        self.smooth_type = entity.dxf.smooth_type
        self.is_2d_polyline = pickle.dumps(entity.is_2d_polyline)
        self.is_3d_polyline = pickle.dumps(entity.is_3d_polyline)
        self.is_polygon_mesh = pickle.dumps(entity.is_polygon_mesh)
        self.is_poly_face_mesh = pickle.dumps(entity.is_poly_face_mesh)
        self.is_closed = pickle.dumps(entity.is_closed)
        self.is_m_closed = pickle.dumps(entity.is_m_closed)
        self.is_n_closed = pickle.dumps(entity.is_n_closed)
        self.has_arc = pickle.dumps(entity.has_arc)
        self.has_width = pickle.dumps(entity.has_width)
        self.mode = entity.get_mode()
        vertices = []
        for v in entity.vertices:
            l, sw, ew, b = v.dxf.location, v.dxf.start_width, v.dxf.end_width, v.dxf.bulge
            v = (l[0], l[1], l[2], sw, ew, b)
            vertices.append(v)
        self.vertices = pickle.dumps(vertices)

    def dxf(self):
        cont = super().dxf()
        cont['dxf']['elevation'] = largebinary_loads(self.elevation)
        cont['dxf']['flags'] = self.flags
        cont['dxf']['default_start_width'] = self.default_start_width
        cont['dxf']['default_end_width'] = self.default_end_width
        cont['dxf']['m_count'] = self.m_count
        cont['dxf']['n_count'] = self.n_count
        cont['dxf']['m_smooth_density'] = self.m_smooth_density
        cont['dxf']['n_smooth_density'] = self.n_smooth_density
        cont['dxf']['smooth_type'] = self.smooth_type
        cont['vertices'], vertices = [], largebinary_loads(self.vertices)
        for v in vertices:
            cont['vertices'].append((v[0], v[1], v[3], v[4], v[5]))
        cont['vertices'] = vertices
        cont['is_2d_polyline'] = largebinary_loads(self.is_2d_polyline)
        cont['is_3d_polyline'] = largebinary_loads(self.is_3d_polyline)
        cont['is_polygon_mesh'] = largebinary_loads(self.is_polygon_mesh)
        cont['is_poly_face_mesh'] = largebinary_loads(self.is_poly_face_mesh)
        cont['is_closed'] = largebinary_loads(self.is_closed)
        cont['is_m_closed'] = largebinary_loads(self.is_m_closed)
        cont['is_n_closed'] = largebinary_loads(self.is_n_closed)
        cont['has_arc'] = largebinary_loads(self.has_arc)
        cont['has_width'] = largebinary_loads(self.has_width)
        cont['mode'] = self.mode
        return cont

    def vector(self):
        cont = super().vector()
        cont['is_closed'] = largebinary_loads(self.is_closed)
        cont['vertices'] = []
        for s in largebinary_loads(self.vertices):
            cont['vertices'].append([s[0], s[1]])
        return cont


class DimensionModel(EntityModel):
    __tablename__ = 'dimension'

    version = integer()
    geometry = string()
    dimstyle = string()
    dimtype = integer()
    defpoint = largebinary()
    defpoint2 = largebinary()
    defpoint3 = largebinary()
    defpoint4 = largebinary()
    defpoint5 = largebinary()
    angle = float()
    leader_length = float()
    text_midpoint = largebinary()
    insert = largebinary()
    attachment_point = integer()
    line_spacing_style = integer()
    line_spacing_factor = float()
    actual_measurement = float()
    dim_text = string()
    oblique_angle = float()
    text_rotation = float()
    horizontal_direction = float()

    def init(self, entity):
        self.left, self.right, self.top, self.bottom = 0, 0, 0, 0
        self.x, self.y = 0, 0
        self.version = entity.dxf.version
        self.geometry = entity.dxf.geometry
        self.dimstyle = entity.dxf.dimstyle
        self.dimtype = entity.dxf.dimtype
        self.defpoint = pickle.dumps(entity.dxf.defpoint)
        self.defpoint2 = pickle.dumps(entity.dxf.defpoint2)
        self.defpoint3 = pickle.dumps(entity.dxf.defpoint3)
        self.defpoint4 = pickle.dumps(entity.dxf.defpoint4)
        self.defpoint5 = pickle.dumps(entity.dxf.defpoint5)
        self.angle = entity.dxf.angle
        self.leader_length = entity.dxf.leader_length
        self.text_midpoint = pickle.dumps(entity.dxf.text_midpoint)
        self.insert = pickle.dumps(entity.dxf.insert)
        self.attachment_point = entity.dxf.attachment_point
        self.line_spacing_style = entity.dxf.line_spacing_style
        self.line_spacing_factor = entity.dxf.line_spacing_factor
        self.actual_measurement = entity.dxf.actual_measurement
        self.dim_text = entity.dxf.text
        self.oblique_angle = entity.dxf.oblique_angle
        self.text_rotation = entity.dxf.text_rotation
        self.horizontal_direction = entity.dxf.horizontal_direction

    def dxf(self):
        cont = super().dxf()
        cont['dxf']['version'] = self.version
        cont['dxf']['geometry'] = self.geometry
        cont['dxf']['dimstyle'] = self.dimstyle
        cont['dxf']['dimtype'] = self.dimtype
        cont['dxf']['defpoint'] = largebinary_loads(self.defpoint)
        cont['dxf']['defpoint2'] = largebinary_loads(self.defpoint2)
        cont['dxf']['defpoint3'] = largebinary_loads(self.defpoint3)
        cont['dxf']['defpoint4'] = largebinary_loads(self.defpoint4)
        cont['dxf']['defpoint5'] = largebinary_loads(self.defpoint5)
        cont['dxf']['angle'] = self.angle
        cont['dxf']['leader_length'] = self.leader_length
        cont['dxf']['text_midpoint'] = largebinary_loads(self.text_midpoint)
        cont['dxf']['insert'] = largebinary_loads(self.insert)
        cont['dxf']['attachment_point'] = self.attachment_point
        cont['dxf']['line_spacing_style'] = self.line_spacing_style
        cont['dxf']['line_spacing_factor'] = self.line_spacing_factor
        cont['dxf']['actual_measurement'] = self.actual_measurement
        cont['dxf']['text'] = self.dim_text
        cont['dxf']['oblique_angle'] = self.oblique_angle
        cont['dxf']['text_rotation'] = self.text_rotation
        cont['dxf']['horizontal_direction'] = self.horizontal_direction
        return cont

    def vector(self):
        cont = super().vector()
        cont['version'] = self.version
        cont['geometry'] = self.geometry
        cont['dimstyle'] = self.dimstyle
        cont['dimtype'] = self.dimtype
        cont['defpoint'] = largebinary_loads(self.defpoint)
        cont['defpoint2'] = largebinary_loads(self.defpoint2)
        cont['defpoint3'] = largebinary_loads(self.defpoint3)
        cont['defpoint4'] = largebinary_loads(self.defpoint4)
        cont['defpoint5'] = largebinary_loads(self.defpoint5)
        cont['angle'] = self.angle
        cont['leader_length'] = self.leader_length
        cont['text_midpoint'] = largebinary_loads(self.text_midpoint)
        cont['insert'] = largebinary_loads(self.insert)
        cont['attachment_point'] = self.attachment_point
        cont['line_spacing_style'] = self.line_spacing_style
        cont['line_spacing_factor'] = self.line_spacing_factor
        cont['actual_measurement'] = self.actual_measurement
        cont['text'] = self.dim_text
        cont['oblique_angle'] = self.oblique_angle
        cont['text_rotation'] = self.text_rotation
        cont['horizontal_direction'] = self.horizontal_direction
        return cont


class TrackModel(EntityModel):
    """ 轨迹线 """
    __tablename__ = 'track'

    points = largebinary()

    def init(self, entity):
        l, r, t, b = None, None, None, None
        for p in entity:
            l, r, t, b = box(l, r, t, b, p)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)
        self.x, self.y = (l + r) / 2, (t + b) / 2
        self.points = largebinary_dumps(entity)
        self.layer = 'track'
        self.dxftype = 'tunnel'  # person | vehicle | tunnel
        self.color = 2
        self.lineweight = 1
        self.linetype = 'BYLAYER'
        self.handle = 'track'
        self.owner = 'track'

    def dxf(self):
        pass

    def vector(self):
        cont = dict()
        cont['id'] = self.id
        cont['type'] = self.dxftype
        cont['left'] = self.left
        cont['right'] = self.right
        cont['top'] = self.top
        cont['bottom'] = self.bottom
        cont['points'] = largebinary_loads(self.points)
        return cont


class PositionModel(EntityModel):
    """ 定位分站 """
    __tablename__ = 'position'

    point = largebinary()
    node_id = integer()

    def init(self, entity):
        self.x, self.y = entity[0], entity[1]
        self.left, self.right = math.floor(self.x), math.ceil(self.x)
        self.top, self.bottom = math.ceil(self.y), math.floor(self.y)
        self.point = largebinary_dumps(entity)
        self.layer = 'position'
        self.dxftype = 'position'
        self.color = 10
        self.lineweight = 3
        self.linetype = 'BYLAYER'
        self.handle = 'position'
        self.owner = 'position'

    def dxf(self):
        pass

    def vector(self):
        cont = dict()
        cont['id'] = self.id
        point = largebinary_loads(self.point)
        cont['x'] = point[0]
        cont['y'] = point[1]
        cont['type'] = self.dxftype
        cont['node_id'] = self.node_id
        cont['track_id'] = int(self.insert_id) if self.insert_id else None
        return cont


class WarningModel(EntityModel):
    """ 预警信息 """
    __tablename__ = 'warning'

    points = largebinary()

    def init(self, entity):
        l, r, t, b = None, None, None, None
        for p in entity:
            l, r, t, b = box(l, r, t, b, p)
        self.left, self.right = math.floor(l), math.ceil(r)
        self.top, self.bottom = math.ceil(t), math.floor(b)
        self.x, self.y = (l + r) / 2, (t + b) / 2
        self.points = largebinary_dumps(entity)
        self.layer = 'warning'
        self.dxftype = 'warning'
        self.color = 1
        self.lineweight = 1
        self.linetype = 'BYLAYER'
        self.handle = 'warning'
        self.owner = 'warning'

    def dxf(self):
        cont = super().dxf()
        return cont

    def vector(self):
        cont = dict()
        cont['id'] = self.id
        cont['type'] = self.dxftype
        cont['left'] = self.left
        cont['right'] = self.right
        cont['top'] = self.top
        cont['bottom'] = self.bottom
        cont['points'] = largebinary_loads(self.points)
        return cont


class DeviceModel(EntityModel):
    """ 监控 """
    __tablename__ = 'device'

    name = string(comment='设备名称')
    code = integer(comment='设备编码')
    type = integer(comment='MonitorSensorType设备类型: 0-监测传感器、1-人员监测分站、2-定位卡')
    sub1 = integer(comment='一级分类,如: 瓦斯传感器')
    sub2 = integer(comment='二级分类,如: 甲烷、风速、微震、一氧化碳、二氧化碳、氧气、温度、馈电、瓦斯含量、瓦斯突出')
    object = integer(comment='MonitorObject监测对象: 0-采区、1-采煤工作面、2-掘进工作面、3-盲区、4-采空区')
    point = largebinary(comment='坐标点')
    device_id = string(comment='设备id，存放node_id的字段')

    def init(self, entity):
        self.x, self.y = entity[0], entity[1]
        self.left, self.right = math.floor(self.x), math.ceil(self.x)
        self.top, self.bottom = math.ceil(self.y), math.floor(self.y)
        self.point = largebinary_dumps(entity)
        self.layer = 'monitor'
        self.dxftype = 'monitor'
        self.color = 10
        self.lineweight = 1
        self.linetype = 'BYLAYER'
        self.handle = 'monitor'
        self.owner = 'monitor'

    def dxf(self):
        pass

    def vector(self):
        cont = dict()
        cont['id'] = self.id
        cont['point'] = largebinary_loads(self.point)
        cont['node_id'] = self.device_id
        cont['device_id'] = self.device_id
        cont['sub1'] = self.sub1
        cont['sub2'] = self.sub2
        cont['name'] = self.name
        return cont


# class BoundaryModel(EntityModel):
#     """井田边界信息"""
#     __tablename__ = 'boundary'
#
#     code = string(comment='井田边界编码')
#     depth = string(comment='开采深度')
#     type = integer(comment='BoundaryType: 0-主井口位置、1-拐点位置、2-边界坐标')
#     points = largebinary(comment='0、1-为点坐标,2为点集合')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         cont = super().vector()
#         return cont
#
#
# class GuidePointModel(EntityModel):
#     """ 导线点 """
#     __tablename__ = 'guide_point'
#
#     name = string(comment='名称')
#     tunnel_id = string(comment='巷道id')
#     index = integer(comment='索引')
#     type = integer(comment='0-默认、1-变坡点、2-拐点、3-交叉点、4-井口、5-马头门、6-井底')
#     point = largebinary(comment='坐标')
#     width = float(comment='巷道宽度')
#     height = float(comment='巷道高度')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         cont = super().dxf()
#         return cont
#
#     def vector(self):
#         cont = super().vector()
#         return cont
#
#
# class TunnelModel(EntityModel):
#     """ 井巷信息表 """
#     __tablename__ = 'tunnel'
#
#     name = string(comment='巷道名称')
#     type = integer(comment='TunnelType: 0-开拓巷道，1-采准巷道，2-回采巷道')
#     workface_id = integer(comment='工作面id')
#     shape = integer(comment='SectionShape: 0-默认（梯形）、1-半圆拱、2-三芯拱、3-矩形、4-圆形、5-高马蹄、6-低马蹄')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         cont = super().dxf()
#         return cont
#
#     def vector(self):
#         cont = super().vector()
#         return cont
#
#
# class WorkingfaceModel(EntityModel):
#     """ 工作面 """
#     __tablename__ = 'workingface'
#
#     name = string(comment='工作面名称')
#     code = string(comment='采区工作面编码')
#     type = integer(comment='WorkingFaceType: 0-默认、1-掘进、2-回采、3-采空、4-采空积水')
#     level = string(comment='开采水平面标高')
#     points = largebinary(comment='工作面坐标信息')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class DrivingModel(EntityModel):
#     """ 掘进位置 """
#     __tablename__ = 'driving'
#
#     workingface_id = integer(comment='工作面id')
#     driving_process = integer(comment='DrivingTechnology: 0-综掘、1-机掘、2-炮掘')
#     shape = integer(comment='SectionShape: 断面形状')
#     width = float(comment='断面宽度')
#     height = float(comment='断面高度')
#     yaw_angle = float(comment='掘进方向角')
#     pitch_angle = float(comment='掘进俯仰角')
#     distance = float(comment='掘进距离')
#     points = largebinary(comment='坐标点')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class RecoveryModel(EntityModel):
#     """ 回采位置 """
#     __tablename__ = 'recovery'
#
#     workingface_id = integer(comment='工作面id')
#     workingface_length = float(comment='工作面id')
#     ctrl_distance = float(comment='控顶距')
#     height = float(comment='采放高度')
#     yaw_angle = float(comment='掘进方向角')
#     pitch_angle = float(comment='掘进俯仰角')
#     distance = float(comment='采放距离')
#     point_x1 = largebinary(comment='坐标X1')
#     point_x2 = largebinary(comment='坐标X2')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class WaterloggedModel(EntityModel):
#     """ 积水区 """
#     __tablename__ = 'waterlogged'
#
#     name = string(comment='积水区名称')
#     code = string(comment='积水区编号')
#     elevation = float(comment='标高')
#     distance = float(comment='探水线距离')
#     warn_distance = float(comment='境界线距离')
#     workingface_id = integer(comment='工作面id')
#     area = float(comment='面积')
#     volume = float(comment='体积')
#     points = largebinary(comment='坐标点')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class ThreeAreaModel(EntityModel):
#     """ 三区 """
#     __tablename__ = 'three_area'
#
#     name = string(comment='三区名称')
#     code = string(comment='三区编号')
#     type = integer(comment='ThreeArea: 0-可采区、1-缓采区、2-禁采区')
#     points = largebinary(comment='坐标点')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class CoalPillarModel(EntityModel):
#     """ 煤柱 """
#     __tablename__ = 'coal_pillar'
#
#     name = string(comment='煤柱名称')
#     code = string(comment='煤柱编号')
#     points = largebinary(comment='坐标点')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class CollapseModel(EntityModel):
#     """ 陷落柱 """
#     __tablename__ = 'collapse'
#
#     name = string(comment='陷落柱名称')
#     code = string(comment='陷落柱编号')
#     area = float(comment='面积')
#     up_extend = float(comment='上延伸')
#     down_extend = float(comment='下延申')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class FaultModel(EntityModel):
#     """ 断层 """
#     __tablename__ = 'fault'
#
#     name = string(comment='断层名称')
#     code = string(comment='断层编码')
#     type = integer(comment='FaultType: 0-正断层、1-逆断层、2-平推断层')
#     tendenty = float(comment='倾向')
#     dip = float(comment='倾角')
#     vertical = float(comment='垂直断距')
#     horizontal = float(comment='水平距离')
#     throw = float(comment='断层落差')
#     left_extend = float(comment='左延伸')
#     right_extend = float(comment='左延伸')
#     up_extend = float(comment='上延伸')
#     down_extend = float(comment='下延伸')
#     disc_type = integer(comment='DiscType: 0-上盘，1-下盘')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class DrillIndexModel(EntityModel):
#     """ 钻孔索引 """
#     __tablename__ = 'drill_index'
#
#     borehole_id = integer(comment='钻孔编号')
#     type = integer(comment='钻孔类型')
#     long = float(comment='经距')
#     lat = float(comment='纬距')
#     elevation = float(comment='标高')
#     location = float(comment='位置')
#     mileage = float(comment='里程')
#     yaw_angle = float(comment='方位角')
#     pitch_angle = float(comment='水平角')
#     rig_type = integer(comment='钻机类型')
#     open_time = date_time(comment='开孔时间')
#     close_time = date_time(comment='终孔时间')
#     close_depth = float(comment='终孔深度')
#     captain = string(comment='机长')
#     recorder = string(comment='记录员')
#     layer_level = string(comment='终孔层位')
#     water_level = float(comment='终孔水位')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class DrillHoleModel(EntityModel):
#     """ 钻孔 """
#     __tablename__ = 'drill_hole'
#
#     borehole_id = integer(comment='钻孔编号')
#     stratum_code = string(comment='地层时代代码')
#     layer_id = integer(comment='分层id')
#     structure = integer(comment='(有/无)结构: 0-有、1-无')
#     canonical = string(comment='岩性代码')
#     mark_layer = string(comment='标志层/煤层代码')
#     lithology = text(comment='岩性描述')
#     yaw_angle = float(comment='方位角')
#     pitch_angle = float(comment='水平角')
#     thickness = float(comment='厚度')
#     core_length = float(comment='岩心长度')
#     sampling_rate = float(comment='取样率')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class DrillLayerModel(EntityModel):
#     """ 钻孔煤层结构分层 """
#     __tablename__ = 'drill_layer'
#
#     borehole_id = integer(comment='钻孔编号')
#     structure_layer_id = integer(comment='结构分层ID')
#     layer_id = integer(comment='分层id')
#     canonical = string(comment='岩性代码')
#     thickness = float(comment='厚度')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class DrillingResultModel(EntityModel):
#     """ 钻孔分析结果 """
#     __tablename__ = 'drill_result'
#
#     borehole_id = integer(comment='钻孔编号')
#     depth = float(comment='深度')
#     point_angle = float(comment='天顶角')
#     azimuth_angle = float(comment='方位角')
#     method = integer(comment='HoleInclinationMethod: 0-中点法(省缺),1-平均孔段法')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class EquipmentModel(EntityModel):
#     """ 设备数据及管件 """
#     __tablename__ = 'equipment'
#
#     name = string(comment='设备名称')
#     code = string(comment='设备编码')
#     type = string(comment='设备类型')
#     system = string(comment='系统名称')
#     manufacturer = string(comment='生产厂商')
#     date = date_time(comment='生产日期')
#     department = string(comment='管理部门')
#     location = string(comment='安设地点')
#     point = largebinary(comment='坐标点')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class PipelineModel(EntityModel):
#     """ 线路及管道 """
#     __tablename__ = 'pipeline'
#
#     name = string(comment='线路名称')
#     type = string(comment='材质类型')
#     start_code = string(comment='开始编码')
#     end_code = string(comment='终点编码')
#     system = string(comment='系统名称')
#     diameter = float(comment='标称直径')
#     location = string(comment='安设地点')
#     manufacturer = string(comment='生产厂商')
#     date = date_time(comment='生产日期')
#     department = string(comment='管理部门')
#     points = largebinary(comment='坐标')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class PipelineXYModel(EntityModel):
#     """ 线路及管道中心线点 """
#     __tablename__ = 'pipeline_xy'
#
#     pipeline_id = integer(comment='线路编码')
#     index = integer(comment='序号')
#     type = integer(comment='类型')
#     width = float(comment='宽度')
#     height = float(comment='高度')
#     point = largebinary(comment='坐标')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class TinIndexModel(EntityModel):
#     """ 地层层面TIN索引表 """
#     __tablename__ = 'tin_index'
#
#     code = string(comment='地层代码')
#     tin_bgn_upndx = integer(comment='顶起始号(TIN结构编号)')
#     tin_end_upndx = integer(comment='顶终止号(TIN结构编号)')
#     tin_bgn_dnndx = integer(comment='底起始号(TIN结构编号)')
#     tin_end_dnndx = integer(comment='底终止号(TIN结构编号)')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class TinStructureModel(EntityModel):
#     """ 地层层面TIN结构(逆时针方向) """
#     __tablename__ = 'tin_structure'
#
#     tin_id = integer(comment='TIN结构编号(自增)')
#     tin_node0 = integer(comment='TIN节点0')
#     tin_node1 = integer(comment='TIN节点1')
#     tin_node2 = integer(comment='TIN节点2')
#     adj_tin0 = integer(comment='邻接三角形序号0')
#     adj_tin1 = integer(comment='邻接三角形序号1')
#     adj_tin2 = integer(comment='邻接三角形序号2')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class TinPointModel(EntityModel):
#     """ TIN结点 """
#     __tablename__ = 'tin_point'
#
#     point = largebinary(comment='坐标')
#     thickness = float(comment='标志层煤层厚度')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         pass
#
#     def vector(self):
#         pass
#
#
# class CoalRegionModel(EntityModel):
#     """ 储量块段 """
#     __tablename__ = 'coal_region'
#
#     mine_code = string(comment='矿井编码')
#     block_key = integer(comment='块段KEY')
#     block_name = string(comment='块段名称')
#     sign = string(comment='煤层代码')
#     coal_type = string(comment='煤种(按国标)')
#     type = string(comment='储量类型')
#     area = float(comment='面积')
#     average_thick = float(comment='平均厚度')
#     average_dip = float(comment='平均倾角')
#     average_rate = float(comment='容量')
#     point = largebinary(comment='坐标')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         cont = super().dxf()
#         return cont
#
#     def vector(self):
#         cont = super().vector()
#         return cont
#
#
# class CoalNatureModel(EntityModel):
#     """ 煤块煤质样品化验表 """
#     __tablename__ = 'coal_nature'
#
#     mine_code = string(comment='矿井编码')
#     block_id = integer(comment='块段Id')
#     block_name = string(comment='样本名称')
#     sh_comb_period = float(comment='最短发火期')
#     fire_tendency = string(comment='自燃倾向')
#     burst_tendency = string(comment='冲击倾向')
#     out_tendency = string(comment='突出倾向')
#     carbon = float(comment='碳含量')
#     sulfur = float(comment='硫含量')
#     vd = float(comment='挥发分vd')
#     vdaf = float(comment='挥发分vdaf')
#     ash_fusion = float(comment='灰熔点')
#     grindability = string(comment='可磨性')
#     mad = float(comment='水分')
#     ash = float(comment='灰分')
#     plastic_thick = float(comment='胶质层厚')
#     oxygen = float(comment='氧浓度')
#     calorific = float(comment='发热量')
#     date = date_time(comment='日期')
#     unit = string(comment='鉴定单位')
#     serial_number = string(comment='xh')
#     point = largebinary(comment='坐标')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         cont = super().dxf()
#         return cont
#
#     def vector(self):
#         cont = super().vector()
#         return cont
#
#
# class GasNatureModel(EntityModel):
#     """ 煤块瓦斯样品化验表 """
#     __tablename__ = 'gas_nature'
#
#     mine_code = string(comment='矿井编码')
#     block_id = integer(comment='块段Id')
#     block_name = string(comment='样本名称')
#     porosity = float(comment='孔隙度')
#     permeability = float(comment='透气系数')
#     oxygen = float(comment='T氧')
#     raw = float(comment='T原')
#     repay = float(comment='T还')
#     t_difference = float(comment='温度差')
#     firm_coefficient = float(comment='坚固系数')
#     decay_rate = string(comment='风化程度')
#     metamorphic = string(comment='变质程度')
#     type = string(comment='结构类型')
#     particle_size = float(comment='松散粒度')
#     apparent_density = float(comment='视密度')
#     adsorption_a = float(comment='吸附常数a')
#     adsorption_b = float(comment='吸附常数b')
#     broken_indicator = string(comment='破碎指标')
#     diffusion_v = float(comment='放散速度')
#     screen_index = float(comment='筛分指数')
#     adsorb = float(comment='吸附变量')
#     apparent_res = float(comment='视电阻率')
#     gas_pressure = float(comment='瓦斯压力')
#     gas_content = float(comment='瓦斯含量')
#     drilling_h2 = float(comment='钻屑Δh2')
#     drilling_k1 = float(comment='钻屑K1')
#     smax = float(comment='钻孔最大钻屑量(L/m)')
#     qmax = float(comment='钻孔最大瓦斯涌出初速度(L/m.min)')
#     date = date_time(comment='日期')
#     unit = string(comment='单位')
#     serial_number = string(comment='xh')
#     point = largebinary(comment='坐标')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         cont = super().dxf()
#         return cont
#
#     def vector(self):
#         cont = super().vector()
#         return cont
#
#
# class CoalPointModel(EntityModel):
#     """ 井巷见煤点 """
#     __tablename__ = 'coal_point'
#
#     mine_code = string(comment='矿井编码')
#     tunnel_id = integer(comment='巷道id')
#     coal_tunnel = string(comment='见煤巷道')
#     coal_place = string(comment='见煤地点')
#     date = date_time(comment='见煤日期')
#     structure = integer(comment='(有/无)结构: 0-有、1-无')
#     sign = string(comment='标志层/煤层代码')
#     canonical_name = string(comment='岩石代码')
#     point = largebinary(comment='坐标')
#     top_lithology = string(comment='顶岩性')
#     bottom_lithology = string(comment='顶岩性')
#     p_top_lithology = string(comment='伪顶岩性')
#     p_top_thickness = float(comment='伪顶厚')
#     p_bottom_lithology = string(comment='伪底岩性')
#     p_bottom_thickness = float(comment='伪底厚')
#     vertical_thickness = float(comment='垂厚')
#     plagioclase = float(comment='斜长')
#     tendenty = float(comment='倾向')
#     dip = float(comment='倾角')
#     use_thickness = float(comment='采用厚度')
#     fracture = float(comment='裂隙发育度')
#     remarks = text(comment='备注')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         cont = super().dxf()
#         return cont
#
#     def vector(self):
#         cont = super().vector()
#         return cont
#
#
# class CoalPointLayerModel(EntityModel):
#     """ 井巷见煤点结构分层 """
#     __tablename__ = 'coal_point_layer'
#
#     mine_code = string(comment='矿井编码')
#     tunnel_id = integer(comment='巷道id')
#     coal_point_id = integer(comment='见煤点ID')
#     structure_layer_id = integer(comment='井巷见煤点结构ID')
#     canonical = string(comment='岩石代码')
#     thickness = float(comment='厚度')
#
#     def init(self, entity):
#         pass
#
#     def dxf(self):
#         cont = super().dxf()
#         return cont
#
#     def vector(self):
#         cont = super().vector()
#         return cont
#
#

class SMVentilateModel(Base):
    """ 安全监控系统 gis 通风装置表格  """
    __tablename__ = 'SMVentilate'

    id = id()
    meta_id = string_index(index=True)
    arrow = float()
    mine_id = string()
    start_x = float()
    start_y = float()
    end_x = float()
    end_y = float()
    ventilateType = string()

    def __init__(self, data):
        self.mine_id = data['mine_id']
        self.meta_id = data['meta_id']
        self.id = data['node_id']
        self.arrow = data['rotation']
        # 存储风向的线段起始点，结束点的坐标（坐标位置就是openlayers的坐标系坐标）
        self.start_x = data['start_x']
        self.start_y = data['start_y']
        self.end_x = data['end_x']
        self.end_y = data['end_y']
        self.ventilateType = data['ventilateType']

    def dxf(self):
        pass

    def vector(self):
        cont = dict()
        cont['id'] = self.id
        cont['meta_id'] = self.meta_id
        cont['arrow'] = self.arrow
        cont['mine_id'] = self.mine_id
        cont['start_x'] = self.start_x
        cont['start_y'] = self.start_y
        cont['end_x'] = self.end_x
        cont['end_y'] = self.end_y
        cont['ventilateType'] = self.ventilateType
        return cont


class MetaJsonModel(Base):
    # 存储图纸转换后的geojson的model
    __tablename__ = 'meta_json'

    id = id()
    meta_id = string()
    version_id = string()
    geojson = longblob()
    update_time = date_time()

    def __init__(self, data):
        self.meta_id = data['meta_id']
        self.version_id = data['version_id']
        self.geojson = data['geojson']
        self.update_time = data['update_time']

    def vector(self):
        cont = dict()
        cont['id'] = self.id
        cont['meta_id'] = self.meta_id
        cont['version_id'] = self.version_id
        cont['geojson'] = self.geojson.decode('utf-8')
        # cont['update_time'] = self.update_time
        return cont